home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 145 / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin / games / spassion / source.lzh / SOURCE / SHOT.C < prev    next >
Text File  |  2000-03-31  |  17KB  |  644 lines

  1. /*
  2. #include <stdio.h>
  3. #include <iocslib.h>
  4. */
  5. #include <XSP2lib.H>
  6. #include "SPASSION.H"
  7. #include "PLAYER.H"
  8. #include "SHOT.H"
  9. #include "PRIORITY.H"
  10. #include "BG.H"
  11. #include "SOUND.H"
  12. #include "SUB.H"
  13. #ifndef NULL
  14. #define NULL ((void *) 0)
  15. #endif
  16.  
  17. #define X_MIN (16)
  18. #define X_MAX (16+255)
  19. #define Y_MIN (16)
  20. #define Y_MAX (16+255)
  21.  
  22. /* ショット用のリスト */
  23. #define SHOT_MAX            100
  24. static SHOT    shot[SHOT_MAX];
  25.  
  26. short MakeConcentShot1( PLAYER *, short );
  27. short MakeConcentShot2( PLAYER *, short );
  28. short MakeConcentShot3( PLAYER *, short );
  29. short MoveConcentShot1( SHOT * );
  30. short MoveConcentShot2( SHOT * );
  31. short MoveConcentShot3( SHOT * );
  32. short    MakeDiffShot1( PLAYER *, short );
  33. short    MakeDiffShot2( PLAYER *, short );
  34. short    MakeDiffShot3( PLAYER *, short );
  35. short    MoveDiffShot1( SHOT * );
  36. short    MoveDiffShot2( SHOT * );
  37. short    MoveDiffShot3( SHOT * );
  38. short MakeChargeShot( PLAYER *, short );
  39. short MoveChargeShot( SHOT * );
  40. short MakeOptionShot( PLAYER *, short );
  41. short MoveOptionShot( SHOT * );
  42.  
  43. /*
  44. Concentration    集中
  45. Diffusion        拡散
  46. */
  47. short    con1_pt[]={0x44,-1};                                    /* 前方集中lev1 */
  48. short    con2_pt[]={0x45,-1};                                    /* 前方集中lev2 */
  49. short    con3_pt[]={0x00,-1};                                    /* 前方集中lev3 ツインレーザー */
  50.  
  51. short    diff1_pt[]={0x46,-1};                                    /* 拡散lev1 前後攻撃 */
  52. short    diff2_pt[]={4,5,6,7,8,9,10,11,12,13,-1};                /* 拡散lev2 リップルレーザー */
  53. short    diff3_pt[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,    /* 拡散lev3 ブーメラン */
  54.                     0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,-1};
  55. short charge_shot_pt[]={14,-1};
  56. short opt1_shot_pt[]={0x30,0x31,0x32,0x33,-1};
  57. short opt2_shot_pt[]={0x40,0x41,0x42,0x43,-1};
  58.  
  59. HIT_XY con1_bghit[] ={ 1,1,-1,-1};
  60. HIT_XY con2_bghit[] ={ 2,2-1,-1};
  61. HIT_XY con3_bghit[] ={ 6,8,14,8,22,8,30,8,-1,-1};
  62. HIT_XY diff1_bghit[]={ 1,1,-1,-1};
  63. HIT_XY diff2_bghit[]={2,2, 3,4, 3,6, 4,8, 5,12, 6,16, 6,20, 6,24, 6,28, 6,32, -1,-1};
  64. HIT_XY diff3_bghit[]={2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
  65.                     2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,-1,-1};
  66. HIT_XY charge_bghit[]={32,16,-1,-1};
  67. HIT_XY opt1_bghit[]={6,2,-1,-1};
  68. HIT_XY opt2_bghit[]={6,3,-1,-1};
  69.  
  70. HIT_XY con1_hit[] ={ 5,5,-1,-1};
  71. HIT_XY con2_hit[] ={ 8,8-1,-1};
  72. HIT_XY con3_hit[] ={ 8,10,16,10,24,10,32,10,-1,-1};
  73. HIT_XY diff1_hit[]={ 4,3,-1,-1};
  74. HIT_XY diff2_hit[]={2,2, 3,4, 3,6, 4,8, 5,12, 6,16, 6,20, 6,24, 6,28, 6,32, -1,-1};
  75. HIT_XY diff3_hit[]={8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  76.                     8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,-1,-1};
  77. HIT_XY charge_hit[]={32,16,-1,-1};
  78. HIT_XY opt1_hit[]={8,2,-1,-1};
  79. HIT_XY opt2_hit[]={8,3,-1,-1};
  80.  
  81. SHOTINFO    shot_info[SHOT_TYPES][POW_LEVELS]={
  82.     /*pow,       pt,   info,       hit, interval,penetration, func_shot_make, func_shot_move, sd_no*/    /*shot_type*/
  83. {    /* 前方集中 */
  84.     {   3, con1_pt,  0x0200,  con1_hit,        6,          0, MakeConcentShot1, MoveConcentShot1, SE_PLAYER_SHOT1 },    /* 0 */
  85.     {   3, con2_pt,  0x0200,  con2_hit,        6,          0, MakeConcentShot2, MoveConcentShot2, SE_PLAYER_SHOT1 },    /* 0 */
  86.     {   2, con3_pt,  0x0200,  con3_hit,        8,          1, MakeConcentShot3, MoveConcentShot3, SE_PLAYER_SHOT3 },    /* 0 */
  87. },
  88. {    /* 拡散 */
  89.     {   2, diff1_pt, 0x0300, diff1_hit ,       6,          0,    MakeDiffShot1,    MoveDiffShot1, SE_PLAYER_SHOT1 },    /* 1 */
  90.     {   1, diff2_pt, 0x0200, diff2_hit,       12,          1,    MakeDiffShot2,    MoveDiffShot2, SE_PLAYER_SHOT2 },    /* 1 */
  91.     {   1, diff3_pt, 0x0200, diff3_hit,       12,          1,    MakeDiffShot3,    MoveDiffShot3, SE_PLAYER_SHOT1 },    /* 1 */
  92. }
  93. };
  94.  
  95. /* 溜め撃ち */
  96. SHOTINFO    charge_shot_info={
  97.     3, charge_shot_pt, 0x0400, charge_hit,  0,          1, MakeChargeShot, MoveChargeShot, SE_PLAYER_SHOT4
  98. };
  99. /*オプションの弾*/
  100. SHOTINFO    opt_shot_info[SHOT_TYPES]={
  101.     /*pow,           pt,   info,      hit,interval,penetration, func_shot_make, func_shot_move, sd_no*/    /*shot_type*/
  102. /* 防御型 */
  103.     {   2, opt1_shot_pt, 0x0200, opt1_hit,      30,          0, MakeOptionShot, MoveOptionShot, SE_PLAYER_SHOT1 },    /* 0 */
  104. /* 攻撃型 */
  105.     {   3, opt2_shot_pt, 0x0200, opt2_hit,      20,          0, MakeOptionShot, MoveOptionShot, SE_PLAYER_SHOT1 }    /* 1 */
  106. };
  107.  
  108. void    InitShot0( void )
  109. {
  110.     short    i,j,k;
  111.  
  112.     for(i=0;i<2;i++){        /* ショットの種類 */
  113.         for(j=0;j<3;j++){    /* ショットのレベル */
  114.             for(k=0;shot_info[i][j].pt[k]!=-1;k++){
  115.                 if( (i==0 && j==2) || (i==1 && j==1) )
  116.                     shot_info[i][j].pt[k]+=obj_shot_b;
  117.                 else
  118.                     shot_info[i][j].pt[k]+=obj_shot;
  119.             }
  120.         }
  121.     }
  122.  
  123.     for(k=0;charge_shot_info.pt[k]!=-1;k++)
  124.         charge_shot_info.pt[k]+=obj_shot_b;
  125.  
  126.     for(i=0;i<2;i++){
  127.         for(k=0;opt_shot_info[i].pt[k]!=-1;k++){
  128.             opt_shot_info[i].pt[k]+=obj_shot;
  129.         }
  130.     }
  131. }
  132. void    InitShot( void )
  133. {
  134.     short    i;
  135.  
  136.     shot_top = NULL;
  137.     shot_free = shot;
  138.     /* ショットデータの初期化 */
  139.     for( i = 0; i < SHOT_MAX; i++ )
  140.         shot[i].next = &shot[i + 1];
  141.     shot[SHOT_MAX - 1].next = NULL;
  142. }
  143.  
  144.  
  145. /*
  146. *    生成
  147. */
  148. /* 前方集中レベル1 */
  149. static short MakeConcentShot1( PLAYER *pl, short num )
  150. {
  151.     SHOTINFO    *sh_info=&shot_info[0][0];
  152.     SHOT        *shot;
  153.  
  154.     shot=MakeShot(10*DOT_RATE,0,sh_info);
  155.     shot->player    = pl;
  156.     shot->lx        = pl->lx+4*DOT_RATE;
  157.     shot->ly        = pl->ly+1*DOT_RATE;
  158.     SetSE( sh_info->sd_no );        /* 効果音 */
  159.     return TRUE;
  160. }
  161. /* 前方集中レベル2 */
  162. static short MakeConcentShot2( PLAYER *pl, short num )
  163. {
  164.     SHOTINFO    *sh_info=&shot_info[0][1];
  165.     SHOT        *shot;
  166.  
  167.     shot=MakeShot(vx_tbl[29][64-4],vy_tbl[29][64-4],sh_info);
  168.     shot->player    = pl;
  169.     shot->lx        = pl->lx+4*DOT_RATE;
  170.     shot->ly        = pl->ly+1*DOT_RATE;
  171.     shot=MakeShot(vx_tbl[29][64+4],vy_tbl[29][64+4],sh_info);
  172.     shot->player    = pl;
  173.     shot->lx        = pl->lx+4*DOT_RATE;
  174.     shot->ly        = pl->ly+1*DOT_RATE;
  175.     shot=MakeShot(vx_tbl[29][64],vy_tbl[29][64],sh_info);
  176.     shot->player    = pl;
  177.     shot->lx        = pl->lx+4*DOT_RATE;
  178.     shot->ly        = pl->ly+1*DOT_RATE;
  179.     SetSE( sh_info->sd_no );        /* 効果音 */
  180.     return TRUE;
  181. }
  182. /* 前方集中レベル3(ツインレーザー) */
  183. static short MakeConcentShot3( PLAYER *pl, short num )
  184. {
  185.     SHOTINFO    *sh_info=&shot_info[0][2];
  186.     SHOT        *shot;
  187.  
  188.     if( !player->laser[0] ){        /*レーザーが出てなければ*/
  189.         shot=MakeShot(10*DOT_RATE,0,sh_info);
  190.         shot->player    = pl;
  191.         shot->lx        = pl->lx;
  192.         shot->ly        = pl->ly;
  193.         shot->box.x1=shot->box.x2        = pl->x;
  194.         shot->box.y1=shot->box.y2        = pl->y-8;
  195.         shot->old_box.x1=shot->old_box.x2        = pl->x;
  196.         shot->old_box.y1=shot->old_box.y2        = pl->y-8;
  197.         shot->box.color=0xFF;
  198.         shot->old_box.color=0;
  199.         shot->arg        = 0;
  200.         pl->laser[0]=1;
  201.     }
  202.     if( !player->laser[1] ){
  203.         shot=MakeShot(10*DOT_RATE,0,sh_info);
  204.         shot->player    = pl;
  205.         shot->lx        = pl->lx;
  206.         shot->ly        = pl->ly;
  207.         shot->box.x1=shot->box.x2        = pl->x;
  208.         shot->box.y1=shot->box.y2        = pl->y+8;
  209.         shot->old_box.x1=shot->old_box.x2        = pl->x;
  210.         shot->old_box.y1=shot->old_box.y2        = pl->y+8;
  211.         shot->box.color=0xFF;
  212.         shot->old_box.color=0;
  213.         shot->arg        = 1;
  214.         pl->laser[1]=1;
  215.         SetSE( sh_info->sd_no );        /* 効果音 */
  216.     }
  217.     return TRUE;
  218. }
  219.  
  220. /* 拡散レベル1 */
  221. static short MakeDiffShot1( PLAYER *pl, short num )
  222. {
  223.     SHOTINFO    *sh_info=&shot_info[1][0];
  224.     SHOT        *shot;
  225.  
  226.     shot=MakeShot(vx_tbl[29][64],vy_tbl[29][64],sh_info);
  227.     shot->player    = pl;
  228.     shot->lx        = pl->lx+4*DOT_RATE;
  229.     shot->ly        = pl->ly+1*DOT_RATE;
  230.     shot=MakeShot(vx_tbl[29][192],vy_tbl[29][192],sh_info);
  231.     shot->player    = pl;
  232.     shot->lx        = pl->lx;
  233.     shot->ly        = pl->ly+1*DOT_RATE;
  234.     shot->info        |= 0x4000;
  235.     SetSE( sh_info->sd_no );        /* 効果音 */
  236.     return TRUE;
  237. }
  238. /* 拡散レベル2(リップル) */
  239. static short MakeDiffShot2( PLAYER *pl, short num )
  240. {
  241.     SHOTINFO    *sh_info=&shot_info[1][1];
  242.     SHOT        *shot;
  243.  
  244.     shot=MakeShot(vx_tbl[25][64],vy_tbl[25][64],sh_info);
  245.     shot->player    = pl;
  246.     shot->lx        = pl->lx;
  247.     shot->ly        = pl->ly;
  248.     shot=MakeShot(vx_tbl[25][192],vy_tbl[25][192],sh_info);
  249.     shot->player    = pl;
  250.     shot->lx        = pl->lx;
  251.     shot->ly        = pl->ly;
  252.     SetSE( sh_info->sd_no );        /* 効果音 */
  253.     return TRUE;
  254. }
  255. /* 拡散レベル3(カッター) */
  256. static short MakeDiffShot3( PLAYER *pl, short num )
  257. {
  258.     SHOTINFO    *sh_info=&shot_info[1][2];
  259.     SHOT        *shot;
  260.     short        j;
  261.  
  262.     for(j=0;j<256;j+=32){
  263.         shot=MakeShot(vx_tbl[29][j],vy_tbl[29][j],sh_info);
  264.         shot->player    = pl;
  265.         shot->lx        = pl->lx;
  266.         shot->ly        = pl->ly;
  267.     }
  268.     SetSE( sh_info->sd_no );        /* 効果音 */
  269.     return TRUE;
  270. }
  271.  
  272. /* 溜め撃ち */
  273. static short MakeChargeShot( PLAYER *pl, short num )
  274. {
  275.     SHOTINFO    *sh_info=&charge_shot_info;
  276.     SHOT        *shot;
  277.  
  278.     shot=MakeShot(5*DOT_RATE,0,sh_info);
  279.     shot->player    = pl;
  280.     shot->lx        = pl->lx;
  281.     shot->ly        = pl->ly;
  282.     SetSE( sh_info->sd_no );        /* 効果音 */
  283.     return TRUE;
  284. }
  285.  
  286. /* オプションショット */
  287. static short MakeOptionShot( PLAYER *pl, short num )
  288. {
  289.     SHOT        *shot;
  290.     short        type=pl->option_type;
  291.     short        *pt[2]={opt1_shot_pt,opt2_shot_pt};
  292.     int            vx[2]={6*DOT_RATE,4*DOT_RATE};
  293.  
  294.     shot=MakeShot(vx[type],0,&opt_shot_info[type]);
  295.     shot->player    = pl;
  296.     shot->lx        = pl->option[num].lx;
  297.     shot->ly        = pl->option[num].ly+( 2*DOT_RATE);
  298.     shot->pt_        = pt[type];
  299.     return TRUE;
  300. }
  301.  
  302. /*
  303. *    動き
  304. */
  305. /* 前方集中レベル1 */
  306. static short MoveConcentShot1( SHOT *shot )
  307. {
  308.     short    x,y,bg;
  309.     shot->x = ((shot->lx += shot->vx) >> 16)-8;    /*-8は表示位置をずらすため*/
  310.     shot->y = ((shot->ly += shot->vy) >> 16)-8;
  311.  
  312.     if( shot->damage
  313.      || SHOT_X > X_MAX+8 )
  314.         return FALSE;
  315.     if( (bg=CheckBGHit(x=SHOT_X-16,y=SHOT_Y-16))!=NON_BG ){
  316.         if( bg==ERASE_BG )
  317.             BreakBG( x, y );
  318.         return FALSE;
  319.     }
  320.     xsp_set_st( shot );
  321.  
  322.     return TRUE;
  323. }
  324. /* 前方集中レベル2 */
  325. static short MoveConcentShot2( SHOT *shot )
  326. {
  327.     short    x,y,bg;
  328.     shot->x = ((shot->lx += shot->vx) >> 16)-8;    /*-8は表示位置をずらすため*/
  329.     shot->y = ((shot->ly += shot->vy) >> 16)-8;
  330.  
  331.     if( shot->damage
  332.      || SHOT_X > X_MAX+8 || SHOT_Y < Y_MIN-8 || SHOT_Y > Y_MAX+8 )
  333.         return FALSE;
  334.     if( (bg=CheckBGHit(x=SHOT_X-16,y=SHOT_Y-16))!=NON_BG ){
  335.         if( bg==ERASE_BG )
  336.             BreakBG( x, y );
  337.         return FALSE;
  338.     }
  339. /*
  340.     if( shot->damage
  341.      || SHOT_X > X_MAX+8 || SHOT_Y < Y_MIN-8 || SHOT_Y > Y_MAX+8 )
  342.         return FALSE;
  343. */
  344.     xsp_set_st( shot );
  345.  
  346.     return TRUE;
  347. }
  348.  
  349. /* 前方集中レベル3(ツインレーザー) */
  350. static short MoveConcentShot3( SHOT *shot )
  351. {
  352.     extern BOX_PTR    *old_box_buf[LASER_BUF_MAX],*box_buf[LASER_BUF_MAX];
  353.     extern short    box_num,old_box_num;
  354.     short    x,y;
  355.  
  356.     shot->old_box.x1=shot->box.x1;
  357.     shot->old_box.y1=shot->box.y1;
  358.     shot->old_box.x2=shot->box.x2;
  359.     shot->old_box.y2=shot->box.y2;
  360.  
  361.     if( shot->box.x2 < 256 ){                /* レーザーの端が画面外に出るまで伸びる */
  362.         shot->box.x1=shot->player->x-16;
  363.         shot->box.x2+=8;
  364.     }else{
  365.         shot->box.x1+=8;
  366.         shot->box.x2+=8;
  367.     }
  368.  
  369.     shot->x=(shot->box.x1+shot->box.x2)/2;shot->hit_x=shot->x-shot->box.x1;
  370.     shot->box.y1=shot->box.y2=shot->y=shot->player->y-16+shot->arg*16-8;
  371.     shot->hit_y=8;
  372.     shot->lx=(shot->x+16) << 16;
  373.     shot->ly=(shot->y+16) << 16;
  374.  
  375.     x=SHOT_X-16;
  376.     for(y=SHOT_Y-shot->hit_y-16;y<SHOT_Y+shot->hit_y-16+8;y+=8){
  377.         if( CheckBGHit(x,y)==ERASE_BG )
  378.             BreakBG( x, y );
  379.     }
  380.  
  381.     if( shot->old_box.x2 < 0 || shot->old_box.x1 > 255
  382.      || shot->player->state!=PLAYER_ALIVE ){
  383.         shot->player->laser[shot->arg] = 0;
  384.         old_box_buf[old_box_num++]=&shot->old_box;
  385.         old_box_num&=31;
  386.         old_box_buf[old_box_num]=(BOX_PTR *)0;
  387.         return FALSE;
  388.     }
  389.  
  390.         box_buf[box_num++]=&shot->box;
  391.         box_num&=31;
  392.         box_buf[box_num]=(BOX_PTR *)0;
  393.     old_box_buf[old_box_num++]=&shot->old_box;
  394.     old_box_num&=31;
  395.     old_box_buf[old_box_num]=(BOX_PTR *)0;
  396.  
  397.     return TRUE;
  398. }
  399.  
  400.  
  401. /* 拡散レベル1 */
  402. static short MoveDiffShot1( SHOT *shot )
  403. {
  404.     short    x,y,bg;
  405.     shot->x = ((shot->lx += shot->vx) >> 16)-8;    /*-8は表示位置をずらすため*/
  406.     shot->y = ((shot->ly += shot->vy) >> 16)-8;
  407.  
  408.     if( shot->damage
  409.     /* (画面右から出た判定と左から出た判定を1回の比較で行っている) */
  410.      || ((unsigned short)shot->x > 256 + 16) )
  411.         return FALSE;
  412.     if( (bg=CheckBGHit(x=SHOT_X-16,y=SHOT_Y-16))!=NON_BG ){
  413.         if( bg==ERASE_BG )
  414.             BreakBG( x, y );
  415.         return FALSE;
  416.     }
  417.     xsp_set_st( shot );
  418.  
  419.     return TRUE;
  420. }
  421. /* 拡散レベル2(リップル) */
  422. static short MoveDiffShot2( SHOT *shot )
  423. {
  424.     short    x,y;
  425.     short    *pt=shot_info[1][1].pt;
  426.     HIT_XY    *hit=shot_info[1][1].hit;
  427.     short    anim_num;
  428.  
  429.     shot->x = ((shot->lx += shot->vx) >> 16);
  430.     shot->y = ((shot->ly += shot->vy) >> 16);
  431.  
  432.     /* (画面右から出た判定と左から出た判定を1回の比較で行っている) */
  433.     if( ((unsigned short)shot->x > 256 + 16) )
  434. /*    if( SHOT_X < X_MIN-8 || SHOT_X > X_MAX+8 )*/
  435.         return FALSE;
  436.  
  437.     x=SHOT_X-16;
  438.     for(y=SHOT_Y-shot->hit_y-16;y<SHOT_Y+shot->hit_y-16+8;y+=8){
  439.         if( CheckBGHit(x,y)==ERASE_BG )
  440.             BreakBG( x, y );
  441.     }
  442.  
  443.     anim_num=(++shot->anim_count)/4;
  444.     if( pt[anim_num] == -1 ){
  445.         shot->anim_count--;
  446.         anim_num--;
  447.     }
  448.     shot->pt=pt[anim_num];
  449.  
  450.     shot->hit_x=hit[anim_num].x;
  451.     shot->hit_y=hit[anim_num].y;
  452.  
  453.     xobj_set_st( shot );
  454.  
  455.     return TRUE;
  456. }
  457. /* 拡散レベル3(カッター) */
  458. static short MoveDiffShot3( SHOT *shot )
  459. {
  460.     short    x,y;
  461.     short    *pt=shot_info[1][2].pt;
  462.     short    anim_num;
  463.  
  464.     shot->x = ((shot->lx += shot->vx) >> 16)-8;    /*-8は表示位置をずらすため*/
  465.     shot->y = ((shot->ly += shot->vy) >> 16)-8;
  466.  
  467.     /* (画面右から出た判定と左から出た判定を1回の比較で行っている) */
  468.     if( ((unsigned short)shot->x > 256 + 16) || ((unsigned short)shot->y > 256 + 16) )
  469. /*    if( SHOT_X < X_MIN-8 || SHOT_X > X_MAX+8 || SHOT_Y < Y_MIN-8 || SHOT_Y > Y_MAX+8 )*/
  470.         return FALSE;
  471.  
  472.     x=SHOT_X-16;
  473.     for(y=SHOT_Y-shot->hit_y-16;y<SHOT_Y+shot->hit_y-16+8;y+=8){
  474.         if( CheckBGHit(x,y)==ERASE_BG )
  475.             BreakBG( x, y );
  476.     }
  477.  
  478.     anim_num=(shot->anim_count++)/4;
  479.     if( pt[anim_num] == -1 ){
  480.         shot->anim_count=0;
  481.         anim_num=0;
  482.     }
  483.     shot->pt=pt[anim_num];
  484.  
  485.     xsp_set_st( shot );
  486.  
  487.     return TRUE;
  488. }
  489.  
  490. /* 溜め撃ち */
  491. static short MoveChargeShot( SHOT *shot )
  492. {
  493.     short    x,y;
  494.     shot->x = ((shot->lx += shot->vx) >> 16);
  495.     shot->y = ((shot->ly += shot->vy) >> 16);
  496.  
  497.     if( SHOT_X > X_MAX+32 )
  498.         return FALSE;
  499.  
  500.     x=SHOT_X-16;
  501.     for(y=SHOT_Y-shot->hit_y-16;y<SHOT_Y+shot->hit_y-16+8;y+=8){
  502.         if( CheckBGHit(x,y)==ERASE_BG )
  503.             BreakBG( x, y );
  504.     }
  505.  
  506.     xobj_set_st( shot );
  507.  
  508.     return TRUE;
  509. }
  510.  
  511. /* オプションショット */
  512. static short MoveOptionShot( SHOT *shot )
  513. {
  514.     short    x,y,bg;
  515.     short    anim_num;
  516.  
  517.     shot->x = ((shot->lx += shot->vx) >> 16)-8;    /*-8は表示位置をずらすため*/
  518.     shot->y = ((shot->ly += shot->vy) >> 16)-8;
  519.  
  520.     if( shot->damage
  521.      || SHOT_X > X_MAX+8 )
  522.         return FALSE;
  523.     if( (bg=CheckBGHit(x=SHOT_X-16,y=SHOT_Y-16))!=NON_BG ){
  524.         if( bg==ERASE_BG )
  525.             BreakBG( x, y );
  526.         return FALSE;
  527.     }
  528.  
  529.     anim_num=(shot->anim_count++)/4;
  530.     if( shot->pt_[anim_num] == -1 ){
  531.         shot->anim_count=0;
  532.         anim_num=0;
  533.     }
  534.     shot->pt=shot->pt_[anim_num];
  535.  
  536.     xsp_set_st( shot );
  537.  
  538.     return TRUE;
  539. }
  540.  
  541. /* --------------- 弾移動 ----------- */
  542. void    MoveShot( void )
  543. {
  544.     SHOT *p,*q;
  545.  
  546.     p = shot_top;        /* 現在注目しているワーク */
  547.     q = NULL;            /* 1つ前のワーク(ワーク削除時に必要) */
  548.  
  549.     while( p ){
  550. #ifdef DEBUG
  551.         if ( !p->func_shot_move ){
  552.             void game_end();
  553.             printf("MoveShot 1\n");
  554.             key_wait();
  555.             game_end();            /* ショットの移動ルーチンがない? */
  556.         }
  557. #endif
  558.         if ( !( *( p->func_shot_move ) )( p ) ) {        /* 弾を移動させる */
  559.             p=EraseShot(p);
  560. #if 0
  561.             if (q == NULL) {    /* リストの一番最初を削除 */
  562.                 shot_top = p->next;
  563.                 p->next = shot_free;
  564.                 shot_free = p;
  565.                 q = NULL;
  566.                 p = shot_top;
  567.             } else {
  568.                 q->next = p->next;
  569.                 p->next = shot_free;
  570.                 shot_free = p;
  571.                 p = q->next;
  572.             }
  573. #endif
  574.         } else {                                    /* 消滅していない時 */
  575. /*            q = p;*/
  576.             p = p->next;
  577.         }
  578.     }
  579. }
  580.  
  581. /*
  582.  *        自弾の発射ルーチン
  583.  */
  584. SHOT    *MakeShot( int vx, int vy, SHOTINFO *sh_info )
  585. {
  586.     SHOT *shot;
  587.  
  588.     /* 空いているか調べる */
  589.     if( !shot_free )return FALSE;
  590.  
  591.     /* 空いているのを探す */
  592.     shot = shot_free;
  593.     shot_free = shot->next;
  594.  
  595.     /* 使っているリストに入れる */
  596.     if( shot->next = shot_top ){
  597.         shot_top->pre = shot;
  598.     }
  599.     shot->pre = NULL;
  600.     shot_top = shot;
  601.  
  602.     /* 各種設定 */
  603.     shot->pt            = sh_info->pt[0];
  604.     shot->info            = sh_info->info | PRIORITY_SHOT;
  605.     shot->vx            = vx;
  606.     shot->vy            = vy;
  607.     shot->hit_x            = sh_info->hit[0].x;
  608.     shot->hit_y            = sh_info->hit[0].y;
  609.     shot->pow            = sh_info->pow;
  610.     shot->penetration    = sh_info->penetration;
  611.     shot->damage        = 0;
  612.     shot->anim_count    = 0;
  613.     shot->func_shot_move= sh_info->func_shot_move;
  614.  
  615.     return shot;
  616. }
  617.  
  618.  
  619. /*
  620.  *        弾消滅
  621.  */
  622. SHOT *EraseShot( SHOT *sh )
  623. {
  624.     SHOT *next;
  625.  
  626.     next = sh->next;
  627.  
  628.     /* 使っているリストから抜く */
  629.     if ( sh->pre ) {
  630.         sh->pre->next = sh->next;
  631.         if ( sh->next ) sh->next->pre = sh->pre;
  632.     } else {
  633.         if ( sh->next ) sh->next->pre = 0;
  634.         shot_top = sh->next;
  635.     }
  636.  
  637.     /* 空いているリストに入れる */
  638.     sh->pre = 0;
  639.     sh->next = shot_free;
  640.     shot_free = sh;
  641.  
  642.     return next;
  643. }
  644.